#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>

#define NR_DIST 10

static int g_end;
static int64_t g_total, g_nr;
static int64_t g_dist[NR_DIST];

void sig_int(int sig)
{
	g_end = 1;
}

int64_t diff(struct timespec *a, struct timespec *b)
{
	int64_t ret = 0;

	ret = a->tv_sec - b->tv_sec;
	ret *= 1000000000L;
	ret += a->tv_nsec - b->tv_nsec;

	return ret;
}

int main()
{
	struct timespec req, remain, now, start;
	int64_t ns;
	int ret;
	int i;

	signal(SIGINT, sig_int);

	while (!g_end) {
		ret = clock_gettime(CLOCK_REALTIME, &start);
		if (ret != 0) {
			perror("gettime");
			exit(1);
		}
		req.tv_sec = start.tv_sec + 1;
		req.tv_nsec = start.tv_nsec;
		ret = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME,
					&req, &remain);
		if (ret != 0) {
			perror("nanosleep");
			continue;
		}

		ret = clock_gettime(CLOCK_REALTIME, &now);
		if (ret != 0) {
			perror("gettime");
			exit(1);
		}

		ns = diff(&now, &req);
		printf("delta=%6ld.%03ld us, start=%ld.%ld sec, req=%ld.%ld sec, now=%ld.%ld sec\n",
			ns/1000, ns%1000,
			start.tv_sec, start.tv_nsec,
			req.tv_sec, req.tv_nsec,
			now.tv_sec, now.tv_nsec);

		g_nr ++;
		g_total += ns;

		for (i = 0; i < NR_DIST && ns > 10; i++) {
			ns /= 10;
		}
		g_dist[i] ++;
	}

	printf("avarage latency %ld nsec\n", g_total/g_nr);
	printf("distribution of latency:\n");
	ns = 1;
	for (i = 0; i < NR_DIST; i++) {
		if (ns*10 < 1000L) {
			printf(" %11ldns -- %11ldns: %ld\n", ns, ns*10, g_dist[i]);
		} else if (ns*10 < 1000000L) {
			printf(" %11ldus -- %11ldus: %ld\n", ns/1000, ns*10/1000, g_dist[i]);
		} else if (ns*10 < 1000000000L) {
			printf(" %11ldms -- %11ldms: %ld\n", ns/1000000L, ns*10/1000000L, g_dist[i]);
		} else {
			printf(" %11ld s -- %11ld s: %ld\n", ns/1000000000L, ns*10/1000000000L, g_dist[i]);
		}
		ns *= 10;
	}

	return 0;
}



